package com.alibaba.cirtus.ots.application.adapter.ability.facade.service.crm;

import com.alibaba.cirtus.ots.application.adapter.ability.model.sdo.SalesPlanStatScItemSDO;
import com.alibaba.cirtus.ots.application.adapter.ability.utils.RequestUtils;
import com.alibaba.citrus.ots.common.annotation.ProcessInvoker;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.common.util.CalculatePercentage;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.epoch.app.bcots.model.dto.BaselineGetOrganizationByIdsRequest;
import com.epoch.app.bcots.model.dto.BatchQueryCompanyRequest;
import com.epoch.app.bcots.model.dto.GetScItemDetailRequest;
import com.epoch.app.bcots.sales_plan.salesplan.dto.LoadSalesPlanRequest;
import com.epoch.app.bcots.sales_plan.salesplan.model.SalesPlan;
import com.epoch.app.bcots.sales_plan.salesplan.service.SalesPlanService;
import com.epoch.app.bcots.service.BaseDataService;
import com.epoch.app.bcots.service.BcOtsService;
import com.epoch.app.otsapplicationadaptersdk.crm.MnCrmIf001Detail;
import com.epoch.app.otsapplicationadaptersdk.crm.MnCrmIf001Request;
import com.epoch.app.otsapplicationadaptersdk.crm.MnCrmIf001SDO;
import com.epoch.app.otsapplicationadaptersdk.crm.mncrmif001.dto.DoHandlerRequest;
import com.epoch.app.otsapplicationadaptersdk.crm.mncrmif001.service.MnCrmIf001Service;
import com.epoch.app.otsapplicationadaptersdk.model.dto.RestCrmPlanSubmissionResponse;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author zhoubc
 * @description: 月度计划提报至CRM
 * @date 2021/9/25 1:06
 */
@Component
public class MnCrmIf001ServiceImpl implements MnCrmIf001Service {
    private final static Log log = Log.getLogger(MnCrmIf001ServiceImpl.class);

    @Resource
    private BaseDataService baseDataService;

    @Resource
    private SalesPlanService salesPlanService;

    @Resource
    private BcOtsService bcOtsService;

    @ProcessInvoker(remark = "MnCrmIf001Service", errorCode = "OTS-02-007-00-16-999", printLog = true)
    @Override
    public Object doHandler(DoHandlerRequest doHandlerRequest) {
        // 类型转换
        String message = doHandlerRequest.getMessage();
        List<SalesPlanStatScItemSDO> statScItemSDOS = JSONObject.parseArray(message, SalesPlanStatScItemSDO.class);
        // 查询月度计划
        SalesPlanStatScItemSDO planStatSdo = statScItemSDOS.stream().findFirst().get();
        LoadSalesPlanRequest planRequest = LoadSalesPlanRequest.builder().id(planStatSdo.getPlanId()).build();
        SalesPlan salesPlan = salesPlanService.loadSalesPlan(planRequest);
        if (null == salesPlan) {
            log.error("MnCrmIf001ServiceImpl#doHandler_fail 月度计划:{}不存在", planStatSdo.getPlanId());
            throw new FacadeException("OTS-02-002-00-16-001");
        }
        // 属性赋值
        MnCrmIf001SDO mnCrmIf001SDO = new MnCrmIf001SDO();
        mnCrmIf001SDO.setOrderNumber(String.valueOf(salesPlan.getId()));
        mnCrmIf001SDO.setSalesOrganizationCode("6000");
        mnCrmIf001SDO.setScItemGroupCode("11");
        // 获取planTime
        try {
            DateTimeFormatter ftf = DateTimeFormatter.ofPattern("yyyyMM");
            String planTime = ftf.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(salesPlan.getPlanTime())), ZoneId.systemDefault()));
            mnCrmIf001SDO.setPlanTime(planTime);
        } catch (Exception e) {
            log.error("MnCrmIf001ServiceImpl#doHandler_fail " + "时间戳转日期失败,planTime="+salesPlan.getPlanTime());
            throw e;
        }
        // 通过业务单元id获取公司外部code
        BaselineGetOrganizationByIdsRequest byIdRequest = BaselineGetOrganizationByIdsRequest.builder()
                .ids(Lists.newArrayList(salesPlan.getOrgBusinessUnitCode())).status(1)
                .build();
        Object obj = baseDataService.baselineGetOrganizationByIds(byIdRequest);
        if (Objects.nonNull(obj)) {
            try {
                String outCode = convertBatchOrg(obj);
                mnCrmIf001SDO.setCustomerCode(outCode);
            } catch (Exception e) {
                log.error("MnCrmIf001ServiceImpl#doHandler_fail " + "业务单元转公司outCode失败 orgBusinessCode=" + salesPlan.getOrgBusinessUnitCode() + ", res=" + obj, e);
                throw e;
            }
        }
        // 转换货品明细
        List<MnCrmIf001Detail> mnCrmIf001Details = statScItemSDOS.stream().map(sdo -> {
            // 如果提报量为0就不提报
            // if (Objects.isNull(sdo.getMonthCount()) || sdo.getMonthCount() == 0) {
            //    return null;
            //}
            MnCrmIf001Detail mnCrmIf001Detail = new MnCrmIf001Detail();
            mnCrmIf001Detail.setEarlyReportQuantity(String.valueOf(sdo.getMonthFirstCount()));
            mnCrmIf001Detail.setMiddleReportQuantity(String.valueOf(sdo.getMonthMiddleCount()));
            mnCrmIf001Detail.setLateReportQuantity(String.valueOf(sdo.getMonthLastCount()));
            mnCrmIf001Detail.setRollingPlanQuantityM1(String.valueOf(sdo.getM1RollingPlanCount()));
            mnCrmIf001Detail.setRollingPlanQuantityM2(String.valueOf(sdo.getM2RollingPlanCount()));
            mnCrmIf001Detail.setRollingPlanQuantityM3(String.valueOf(sdo.getM3RollingPlanCount()));
            if (Objects.isNull(sdo.getBeforeMonthMoney())) {
                sdo.setBeforeMonthMoney(0L);
            }
            if (Objects.nonNull(sdo.getMonthCount())) {
                BigDecimal averagePrice = CalculatePercentage.retainTwoBigDecimalPercentage(new BigDecimal(sdo.getBeforeMonthMoney()), new BigDecimal(sdo.getMonthCount() * 100));
                /**
                 * 按产品要求，提报量为0时，赋值30
                 */
                mnCrmIf001Detail.setAveragePrice(BigDecimal.ZERO.equals(averagePrice) ? "30.00": averagePrice.toString());
            }
            GetScItemDetailRequest id = GetScItemDetailRequest.builder().id(sdo.getScItemId()).build();
            try {
                Map scItemDetailMap = (Map) baseDataService.getScItemDetail(id);
                Map result = (Map) scItemDetailMap.get("result");
                Map detail = (Map) result.get("result");
                String outerId = (String) detail.get("outerId");
                mnCrmIf001Detail.setScItemCode(outerId);
            } catch (Exception e) {
                log.error("MnCrmIf001ServiceImpl#doHandler_fail " + "货品outerId转换失败，itemId=" + sdo.getScItemId(), e);
                throw e;
            }
            return mnCrmIf001Detail;
        }).filter(Objects::nonNull).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(mnCrmIf001Details)) {
            mnCrmIf001SDO.setItems(mnCrmIf001Details);
            MnCrmIf001Request mnCrmIf001Request = new MnCrmIf001Request();
            mnCrmIf001Request.setMessageHeader(RequestUtils.generateMessageHeader("MnCrmIf001", "CRM"));
            mnCrmIf001Request.setData(Lists.newArrayList(mnCrmIf001SDO));
            // 提报时不变更状态，回调告诉我们成功再去变更状态
            Map map = Maps.newHashMap();
            try {
                map = doHandler$callAPI(mnCrmIf001Request);
            } catch (Exception e) {
                log.error("MnCrmIf001ServiceImpl#doHandler_fail " + "调用crm接口失败, req=" + mnCrmIf001Request, e);
            }
            return map;
        } else {
            return RestCrmPlanSubmissionResponse.builder().build();
        }
    }

    private String convertBatchOrg(Object obj) {
        JSONObject o = JSONObject.parseObject(JSONObject.toJSONString(obj));
        if (o != null) {
            JSONArray array = o.getJSONArray("result");
            if (array.size() > 0) {
                JSONObject j = array.getJSONObject(0).getJSONObject("organizationSDO");
                String bidId = (String) j.get("bizId");
                BatchQueryCompanyRequest companyRequest = BatchQueryCompanyRequest.builder().ids(Lists.newArrayList(bidId)).build();
                Map map = (Map) bcOtsService.batchQueryCompany(companyRequest);
                Map result = (Map) map.get("result");
                List<Map> content = (List<Map>) result.get("content");
                Map company = content.get(0);
                String outCode = (String) company.get("outCode");
                return outCode;
            }
        }
        return null;
    }
}
